'''
Created on 29/09/2014

@author: David
'''
from Sodev.pcb import Pcb
from Sodev.hardDrive import Harddrive
from Sodev.memoryAdmin import Memoryadmin
from Sodev.pantalla import Pantalla
from Sodev.fileSystem import FileSystem

class Kernel:
    def __init__(self, scheduler):
        self.pantalla = Pantalla()
        self.harddrive = Harddrive()
        self.memoryadmin = Memoryadmin()
        self.currentpid = 0
        self.scheduler = scheduler
        self.poolPCBkilled = []
        self.fs = FileSystem()
        self.fs.obtainIndexOf(self.harddrive)
    
     
    def setprogramToScheduler(self,path):
        programData = self.fs.search(path).getData()
        if(len(self.poolPCBkilled)>0):
            pcb = self.poolPCBkilled.pop()
            pcb.setPc(0)
            self.memoryadmin.writeProgram(programData,pcb.getPid())
        else:
            pcb = Pcb(0,None,self.currentpid, None, 0)
            self.memoryadmin.writeProgram(programData,pcb.getPid())
            self.currentpid = self.currentpid + 1
        self.scheduler.agregarPcb(pcb, programData)
        
    #Ejecuta una lista de programas, que los carga en la cola de ready y memoria, y luego los ejecuta
    def runMultiplePrograms(self,programs):
        for prog in programs:
            self.setprogramToScheduler("/"+prog.getNombre())
        self.scheduler.runPcb()
        
    
    def createFolder(self,name, path):
        self.fs.createFolder(name, path)    
    
    ##Deprecado
    def runII(self,path):
        programData = self.fs.search(path).getData()
        if(len(self.poolPCBkilled)>0):
            pcb = self.poolPCBkilled.pop()
            pcb.setPc(0)
            self.memoryadmin.writeProgram(programData,pcb.getPid())
        else:
            pcb = Pcb(0,None,self.currentpid, None, 0)
            self.memoryadmin.writeProgram(programData,pcb.getPid())
            self.currentpid = self.currentpid + 1
        self.scheduler.agregarPcb(pcb, programData)
        self.scheduler.runPcb()
    
    def runIII(self,path):
        self.setprogramToScheduler(path)
        self.scheduler.runPcb() 
     
    def getFirstPcb(self):
        return self.pcbs.pop()
    
    def writeProgramOnHD(self,path ,programa):
        self.fs.writeProgram(path, programa)
        
    def pasarAlSiguientePCB(self):
        self.getScheduler().next()
        
    def killPCB(self, pcb):
        self.freeMemOfPCb(pcb)
        pcb.reset()
        self.poolPCBkilled.append(pcb)
        
    def freeMemOfPCb(self, pcb):
        self.memoryadmin.liberarMemoria(pcb)
        
    def reanudarPCB(self, pcb):
        self.scheduler.reanudarPCB(pcb)        
        
    def getScheduler(self):
        return self.scheduler

    def setMMU(self,MMU):
        self.memoryadmin = MMU